package thomas.javase.threads;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicInteger;

public class ThreadPool {

    private final int THREAD_POOL_NUMBERS = 10;
    private ExecutorService executorService = Executors.newFixedThreadPool(THREAD_POOL_NUMBERS);

    private class Action implements Runnable{
        private final int start;
        /**
         * countDownLatch这个类使一个线程等待其他线程各自执行完毕后再执行。
         * 是通过一个计数器来实现的，计数器的初始值是线程的数量。
         * 每当一个线程执行完毕后，计数器的值就-1，当计数器的值为0时，表示所有线程都执行完毕，然后在闭锁上等待的线程就可以恢复工作了。
         *
         */
        private final CountDownLatch watch;
        //private final java.util.concurrent.ConcurrentHashMap ;
        //java.util.concurrent.CopyOnWriteArrayList;
        //private final Future<Integer> counts;
        private java.util.concurrent.atomic.AtomicInteger counts ;

        public Action(int start, CountDownLatch watch, AtomicInteger counts){
            this.start = start;
            this.watch = watch;
            this.counts = counts;
        }

        @Override
        public void run(){
            for(int i=0; i < 10; i++) {
                System.out.println(Thread.currentThread().getName() + " Action running:  " + start + " == "+ i);
                counts.incrementAndGet();
                System.out.println(Thread.currentThread().getName() + "  counts:  " +  counts.get());
            }
            watch.countDown();
        }
    }

    public void callThreads()throws InterruptedException{
        CountDownLatch watch = new CountDownLatch(5);
        AtomicInteger counts = new AtomicInteger(0);
        System.out.println("===  main start  ===");
        for(int i=5; i < 10; i++) {
            this.executorService.execute(new Action(i, watch, counts));
        }
        watch.await();//调用await()方法的线程会被挂起，它会等待直到count值为0才继续执行
        System.out.println("===  main end  ===");
    }
    public static void main(String[] args) throws InterruptedException{
        ThreadPool threadPool = new ThreadPool();
        threadPool.callThreads();
    }
}
